package com.irdstudio.efp.esb.api.service.sed.ploaninfo;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.irdstudio.basic.framework.core.constant.EsbRetCodeStandard;
import com.irdstudio.basic.framework.core.constant.SDicCertTypeEnum;
import com.irdstudio.basic.framework.core.constant.SDicToLocalConstant;
import com.irdstudio.basic.framework.core.exception.BizException;
import com.irdstudio.basic.framework.core.util.DateUtility;
import com.irdstudio.basic.framework.core.util.sdic.SDicToLocal;
import com.irdstudio.efp.console.common.ConsoleConstant;
import com.irdstudio.efp.cus.service.facade.CusIndivService;
import com.irdstudio.efp.cus.service.vo.CusIndivVO;
import com.irdstudio.efp.esb.api.bean.sed.ploaninfo.AccLoanArry;
import com.irdstudio.efp.esb.api.bean.sed.ploaninfo.YedReqLoanInfoQuery;
import com.irdstudio.efp.esb.api.bean.sed.ploaninfo.YedRespLoanInfoQuery;
import com.irdstudio.efp.esb.api.common.EsbRespServiceBeanCreator;
import com.irdstudio.efp.esb.api.common.sed.PersonalLoanQryTypeEnum;
import com.irdstudio.efp.esb.common.constant.EsbSysHeadEnums;
import com.irdstudio.efp.esb.common.server.req.EsbReqServiceBean;
import com.irdstudio.efp.esb.common.server.resp.EsbRespServiceBean;
import com.irdstudio.efp.esb.service.bo.req.hj.RepAccLoanDetailsQueryBean;
import com.irdstudio.efp.esb.service.bo.req.hj.RepAccLoanInfoQueryBean;
import com.irdstudio.efp.esb.service.bo.resp.hj.LoanDetailsArry;
import com.irdstudio.efp.esb.service.bo.resp.hj.RespAccLoanDetailsQueryBean;
import com.irdstudio.efp.esb.service.bo.resp.hj.RespAccLoanInfoQueryBean;
import com.irdstudio.efp.esb.service.facade.hj.AccLoanDetailsQueryService;
import com.irdstudio.efp.esb.service.facade.hj.AccLoanInfoQueryService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;


/**
 * @author
 * @version 0.1
 * @date 2020-08-05
 */
@Service("yedLoanInfoQueryService")
public class YedLoanInfoQueryService {

    private static Logger logger = LoggerFactory.getLogger(YedLoanInfoQueryService.class);

    // 默认第一页
    private final String DEFAULT_PAGE_NO = "1";
    // 默认每页显示10条记录
    private final String DEFAULT_PAGE_SIZE = "10";

    @Autowired
    @Qualifier("cusIndivService")
    private CusIndivService cusIndivService;

    @Autowired
    @Qualifier("accLoanInfoQueryService")
    private AccLoanInfoQueryService accLoanInfoQueryService;

    @Autowired
    @Qualifier("accLoanDetailsQueryService")
    private AccLoanDetailsQueryService accLoanDetailsQueryService;

    /**
     * 根据查询类型封装查询参数
     *
     * @param qryType             查询类型
     * @param yedReqLoanInfoQuery
     * @throws Exception
     */
    public YedLoanInfoQueryParams transferQueryParams(String qryType, YedReqLoanInfoQuery yedReqLoanInfoQuery) throws Exception {

        YedLoanInfoQueryParams params = new YedLoanInfoQueryParams();
        switch (PersonalLoanQryTypeEnum.getQryType(qryType)) {
            case QUERY_TYPE_08: {
                //08.单个客户下所有的已结清借据信息查询--证件号、证件类型必输
                if (certTpPredicate.test(yedReqLoanInfoQuery) && certNoPredicate.test(yedReqLoanInfoQuery)) {
                    throw new BizException("证件类型、证件号码不能为空");
                }
                if (certTpPredicate.test(yedReqLoanInfoQuery)) {
                    throw new BizException("证件类型不能为空");
                }
                if (certNoPredicate.test(yedReqLoanInfoQuery)) {
                    throw new BizException("证件号码不能为空");
                }

                //证件类型
                params.setIdentTp(yedReqLoanInfoQuery.getIdentTp());
                //证件号码
                params.setIdentNo(yedReqLoanInfoQuery.getIdentNo());
                //是否结清标识（是）
                params.setSetlFlg(ConsoleConstant.ACC_QUERY_1);
                //是否过滤标识
                params.setFltrtnFlg("N");
                break;
            }
            case QUERY_TYPE_09: {
                //09.单个客户下所有的未结清借据信息查询--证件号、证件类型必输
                if (certTpPredicate.test(yedReqLoanInfoQuery) && certNoPredicate.test(yedReqLoanInfoQuery)) {
                    throw new BizException("证件类型、证件号码不能为空");
                }
                if (certTpPredicate.test(yedReqLoanInfoQuery)) {
                    throw new BizException("证件类型不能为空");
                }
                if (certNoPredicate.test(yedReqLoanInfoQuery)) {
                    throw new BizException("证件号码不能为空");
                }

                //证件类型
                params.setIdentTp(yedReqLoanInfoQuery.getIdentTp());
                //证件号码
                params.setIdentNo(yedReqLoanInfoQuery.getIdentNo());
                //是否结清标识（否）
                params.setSetlFlg(ConsoleConstant.ACC_QUERY_2);
                //是否过滤标识
                params.setFltrtnFlg("N");
                //如果“每页显示条数”为0时，不返回借据数组
                if ("0".equals(yedReqLoanInfoQuery.getPerPgDsplCnt()))
                    params.setFlag("Y");
                break;
            }
            case QUERY_TYPE_10: {
                //10.单个客户下所有的未结清、需要过滤的借据信息查询--证件号、证件类型必输
                if (certTpPredicate.test(yedReqLoanInfoQuery) && certNoPredicate.test(yedReqLoanInfoQuery)) {
                    throw new BizException("证件类型、证件号码不能为空");
                }
                if (certTpPredicate.test(yedReqLoanInfoQuery)) {
                    throw new BizException("证件类型不能为空");
                }
                if (certNoPredicate.test(yedReqLoanInfoQuery)) {
                    throw new BizException("证件号码不能为空");
                }

                //证件类型
                params.setIdentTp(yedReqLoanInfoQuery.getIdentTp());
                //证件号码
                params.setIdentNo(yedReqLoanInfoQuery.getIdentNo());
                //是否结清标识（否）
                params.setSetlFlg(ConsoleConstant.ACC_QUERY_2);
                //是否过滤标识
                params.setFltrtnFlg("Y");
                break;
            }
            default: {
                throw new BizException("你输入的查询类型有误，请重新输入");
            }
        }
        return params;
    }

    public YedRespLoanInfoQuery getLoanInfo(YedLoanInfoQueryParams params, String qryType, YedReqLoanInfoQuery yedReqLoanInfoQuery, String glblSrlNo) throws Exception {
        //响应体
        YedRespLoanInfoQuery yedRespLoanInfoQuery = new YedRespLoanInfoQuery();
        //根据证件类型、证件号码查询核心客户号
        CusIndivVO cusIndivVO = new CusIndivVO();
        cusIndivVO.setCertType(params.getIdentTp());
        cusIndivVO.setCertCode(params.getIdentNo());
        cusIndivVO = cusIndivService.queryByCust(cusIndivVO);
        if (Objects.isNull(cusIndivVO)) {
            throw new Exception("客户信息不存在");
        }
        //根据不同的查询场景，调用互金的不同接口查询
        //08查询已结清数据
        if ((PersonalLoanQryTypeEnum.QUERY_TYPE_08.getValue().equals(qryType))) {
            RespAccLoanInfoQueryBean respAccLoanInfoQueryBean = loanInfoQuery(params, yedReqLoanInfoQuery, glblSrlNo, cusIndivVO);
            RespAccLoanDetailsQueryBean respAccLoanDetailsQueryBean = loanDetailsQuery(params, yedReqLoanInfoQuery, glblSrlNo, cusIndivVO);
            //组装响应体返回
            yedRespLoanInfoQuery = setLoanInfo(yedRespLoanInfoQuery, respAccLoanInfoQueryBean);
            yedRespLoanInfoQuery = setLoanDetails(yedRespLoanInfoQuery, yedReqLoanInfoQuery, respAccLoanDetailsQueryBean);
        }
        //09查询未结清数据
        if ((PersonalLoanQryTypeEnum.QUERY_TYPE_09.getValue().equals(qryType))) {
            if ("Y".equals(params.getFlag())) {
                //如果查询类型为09，且“每页显示条数”为0时，只调互金30230010_01接口
                RespAccLoanInfoQueryBean respAccLoanInfoQueryBean = loanInfoQuery(params, yedReqLoanInfoQuery, glblSrlNo, cusIndivVO);
                if (Objects.isNull(respAccLoanInfoQueryBean)) {
                    throw new RuntimeException("借据信息总数查询失败，请稍后再试");
                }
                //组装响应体返回
                yedRespLoanInfoQuery = setLoanInfo(yedRespLoanInfoQuery, respAccLoanInfoQueryBean);
            } else {
                //否则都需返回
                RespAccLoanInfoQueryBean respAccLoanInfoQueryBean = loanInfoQuery(params, yedReqLoanInfoQuery, glblSrlNo, cusIndivVO);
                RespAccLoanDetailsQueryBean respAccLoanDetailsQueryBean = loanDetailsQuery(params, yedReqLoanInfoQuery, glblSrlNo, cusIndivVO);
                if (Objects.isNull(respAccLoanInfoQueryBean) || Objects.isNull(respAccLoanDetailsQueryBean)) {
                    throw new RuntimeException("借据详细信息查询失败，请稍后再试");
                }
                //组装响应体返回
                yedRespLoanInfoQuery = setLoanInfo(yedRespLoanInfoQuery, respAccLoanInfoQueryBean);
                yedRespLoanInfoQuery = setLoanDetails(yedRespLoanInfoQuery, yedReqLoanInfoQuery, respAccLoanDetailsQueryBean);
            }
        }
        if ((PersonalLoanQryTypeEnum.QUERY_TYPE_10.getValue().equals(qryType))) {
            RespAccLoanInfoQueryBean respAccLoanInfoQueryBean = loanInfoQuery(params, yedReqLoanInfoQuery, glblSrlNo, cusIndivVO);
            RespAccLoanDetailsQueryBean respAccLoanDetailsQueryBean = loanDetailsQuery(params, yedReqLoanInfoQuery, glblSrlNo, cusIndivVO);
            if (Objects.isNull(respAccLoanInfoQueryBean) || Objects.isNull(respAccLoanDetailsQueryBean)) {
                throw new RuntimeException("借据详细信息查询失败，请稍后再试");
            }
            //组装响应体返回
            yedRespLoanInfoQuery = setLoanInfo(yedRespLoanInfoQuery, respAccLoanInfoQueryBean);
            yedRespLoanInfoQuery = setLoanDetails(yedRespLoanInfoQuery, yedReqLoanInfoQuery, respAccLoanDetailsQueryBean);
        }
        return yedRespLoanInfoQuery;
    }


    /**
     * 调用互金借据信息明细30230006_07接口
     *
     * @param params
     * @param yedReqLoanInfoQuery
     * @param glblSrlNo
     * @param cusIndivVO
     * @return
     */
    private RespAccLoanDetailsQueryBean loanDetailsQuery(YedLoanInfoQueryParams params, YedReqLoanInfoQuery yedReqLoanInfoQuery, String glblSrlNo, CusIndivVO cusIndivVO) {
        RepAccLoanDetailsQueryBean repAccLoanDetailsQueryBean = new RepAccLoanDetailsQueryBean();
        repAccLoanDetailsQueryBean.setCustAcctNo(cusIndivVO.getInnerCusId());
        repAccLoanDetailsQueryBean.setSetlFlg(params.getSetlFlg());
        repAccLoanDetailsQueryBean.setPerPgRcrdCnt(yedReqLoanInfoQuery.getPerPgDsplCnt());
        repAccLoanDetailsQueryBean.setPgNo(yedReqLoanInfoQuery.getPgNO());
        repAccLoanDetailsQueryBean.setFltrtnFlg(params.getFltrtnFlg());
        RespAccLoanDetailsQueryBean respAccLoanDetailsQueryBean = accLoanDetailsQueryService.loanDetailsQuery(repAccLoanDetailsQueryBean, glblSrlNo);
        return respAccLoanDetailsQueryBean;
    }

    /**
     * 调用互金借据信息总数30230010_01接口
     *
     * @param params
     * @param yedReqLoanInfoQuery
     * @param glblSrlNo
     * @param cusIndivVO
     * @return
     * @throws Exception
     */
    private RespAccLoanInfoQueryBean loanInfoQuery(YedLoanInfoQueryParams params, YedReqLoanInfoQuery yedReqLoanInfoQuery, String glblSrlNo, CusIndivVO cusIndivVO) throws Exception {
        RepAccLoanInfoQueryBean repAccLoanInfoQueryBean = new RepAccLoanInfoQueryBean();
        repAccLoanInfoQueryBean.setCustAcctNo(cusIndivVO.getInnerCusId());
        repAccLoanInfoQueryBean.setSetlFlg(params.getSetlFlg());
        repAccLoanInfoQueryBean.setPerPgRcrdCnt(yedReqLoanInfoQuery.getPerPgDsplCnt());
        repAccLoanInfoQueryBean.setPgNo(yedReqLoanInfoQuery.getPgNO());
        RespAccLoanInfoQueryBean respAccLoanInfoQueryBean = accLoanInfoQueryService.loanInfoQuery(repAccLoanInfoQueryBean, glblSrlNo);
        return respAccLoanInfoQueryBean;
    }

    /**
     * 组装借据信息总数返回
     *
     * @param yedRespLoanInfoQuery
     * @param respAccLoanInfoQueryBean
     * @return
     */
    private YedRespLoanInfoQuery setLoanInfo(YedRespLoanInfoQuery yedRespLoanInfoQuery, RespAccLoanInfoQueryBean respAccLoanInfoQueryBean) {
        yedRespLoanInfoQuery.setNxtTrmRpyblTotAmt(respAccLoanInfoQueryBean.getNxtTrmRpymtAmt());
        yedRespLoanInfoQuery.setNxtTrmRpymtDt(respAccLoanInfoQueryBean.getNxtTrmRpymtDt());
        yedRespLoanInfoQuery.setDbllTotCnt(respAccLoanInfoQueryBean.getDbllTotCnt());
        return yedRespLoanInfoQuery;
    }

    /**
     * 组装借据信息总数返回
     *
     * @param yedRespLoanInfoQuery
     * @param respAccLoanDetailsQueryBean
     * @return
     */
    private YedRespLoanInfoQuery setLoanDetails(YedRespLoanInfoQuery yedRespLoanInfoQuery, YedReqLoanInfoQuery yedReqLoanInfoQuery, RespAccLoanDetailsQueryBean respAccLoanDetailsQueryBean) throws Exception {
        ArrayList<AccLoanArry> loanInfArries = new ArrayList<>();
        List<LoanDetailsArry> loanDetailsArry = respAccLoanDetailsQueryBean.getDbllArry();
        for (LoanDetailsArry detailsArry : loanDetailsArry) {
            AccLoanArry msgInfoArry = new AccLoanArry();
            //借据编号
            msgInfoArry.setDbllNo(detailsArry.getAcctMjrKey());
            //贷款号
            msgInfoArry.setLoanNo(detailsArry.getLoanNo());
            //借据金额
            msgInfoArry.setDbllAmt(detailsArry.getContrOriglAmt());
            //借据余额
            msgInfoArry.setDbllBal(detailsArry.getLoanBal());
            //借据起始日
            msgInfoArry.setDbllStrtDay(Objects.isNull(detailsArry.getContrStrtDt()) ? "" : DateUtility.format8To10(detailsArry.getContrStrtDt()));
            //借据到期日
            msgInfoArry.setDbllMtrDay(Objects.isNull(detailsArry.getContrStopDt()) ? "" : DateUtility.format8To10(detailsArry.getContrStopDt()));
            //借据状态
            msgInfoArry.setDbllSt(detailsArry.getAcctSt());
            //执行年利率
            msgInfoArry.setExecAnulIntRt(Objects.isNull(detailsArry.getNrlIntRt()) ? BigDecimal.ZERO : detailsArry.getNrlIntRt().divide(new BigDecimal("100")));
            //贷款期限
            msgInfoArry.setLoanTrm(detailsArry.getTrm());
            //利率期限单位
            msgInfoArry.setIntRtTrmUnit(detailsArry.getTrmTp());
            //还款方式
            msgInfoArry.setRpymtMd(SDicToLocal.getLocalSysDicVal(SDicToLocalConstant.REPAY_WAY, detailsArry.getPlnMd()));
            //还款卡号
            msgInfoArry.setRpymtCardNo(detailsArry.getPymtAcct());
            //放款卡号
            msgInfoArry.setDistrCardNo(detailsArry.getAutoWthhdAcct());
            //还款周期
            msgInfoArry.setRpymtCyc(setlCyc(detailsArry.getIntSetlCyc()));
            //还款日期
            msgInfoArry.setRpymtDt(detailsArry.getIntSetlDay());
            //应收利息累计
            msgInfoArry.setRcvbIntAcmln(detailsArry.getRpyblNonRpymtIntTot());
            //实收利息累计
            msgInfoArry.setPclupIntAcmln(detailsArry.getAlrdyRpymtInt());
            //应收未收罚息
            msgInfoArry.setRcvbUncolcdPnyInt(detailsArry.getRpyblNonRpymtPnyIntTot());
            //已偿还罚息
            msgInfoArry.setRpydPnyInt(detailsArry.getAlrdyRpymtPnyInt());
            //应收复利累计
            msgInfoArry.setRcvbCmpdIntAcmln(detailsArry.getRpyblNonRpymtCmpdIntTot());
            //实收复利
            msgInfoArry.setPclupCmpdInt(detailsArry.getAlrdyRpymtCmpdInt());
            //下期还款日期
            msgInfoArry.setNxtTrmRpymtDt((detailsArry.getNxtIntSetlDt()));
            //下期还款金额
            msgInfoArry.setNxtTrmRpymtAmt(detailsArry.getNxtRpymtAmt());
            //剩余期数
            msgInfoArry.setRmanTrmCnt(detailsArry.getRmanTrmCnt());
            //贷款用途 --23:消费支出(送固定值)
            msgInfoArry.setLoanPps("23");
            //已结清时间
            msgInfoArry.setAlrdySetlTm(Objects.isNull(detailsArry.getSetlDt()) ? "" : DateUtility.format8To10(detailsArry.getSetlDt()));
            //计提利息
            msgInfoArry.setPrvnInt(detailsArry.getAlrdyPrvnInt());
            //欠款金额
            msgInfoArry.setArsAmt(detailsArry.getArsAmt());
            //宽限日
            msgInfoArry.setGrcPrd(Objects.isNull(detailsArry.getGrcPrd()) ? "" : DateUtility.format8To10(detailsArry.getGrcPrd()));
            loanInfArries.add(msgInfoArry);
        }
        //总笔数
        yedRespLoanInfoQuery.setTotCnt(respAccLoanDetailsQueryBean.getTotRcrdCnt());
        //每页显示条数
        yedRespLoanInfoQuery.setPerPgDsplCnt(yedReqLoanInfoQuery.getPerPgDsplCnt());
        //页码
        yedRespLoanInfoQuery.setPgNo(yedReqLoanInfoQuery.getPgNO());
        yedRespLoanInfoQuery.setAccLoanArryList(loanInfArries);
        return yedRespLoanInfoQuery;
    }

    /**
     * 证件类型预言为空 或者 非法的证件类型
     */
    private final Predicate<YedReqLoanInfoQuery> certTpPredicate = (p) -> {
        if (StringUtils.isEmpty(p.getIdentTp())) {
            return true;
        }
        //非法的证据类型也返回true
        SDicCertTypeEnum[] values = SDicCertTypeEnum.values();
        List<SDicCertTypeEnum> sDicCertTypeEnums = Arrays.asList(values);
        for (SDicCertTypeEnum sDicCertTypeEnum : sDicCertTypeEnums) {
            if (sDicCertTypeEnum.getValue().equals(p.getIdentTp())) {
                return false;
            }
        }
        return true;
    };
    /**
     * 证件号码预言为空
     */
    private final Predicate<YedReqLoanInfoQuery> certNoPredicate = (p) -> StringUtils.isEmpty(p.getIdentNo());

    /**
     * 发生异常时候封装EsbRespServiceBean
     *
     * @param esbReqServiceBean
     * @param exception
     * @param pageNo
     * @param pageSize
     * @param yedRespLoanInfoQuery
     * @return
     */
    public EsbRespServiceBean getEsbRespServiceBean(EsbReqServiceBean esbReqServiceBean, Exception exception, String pageNo, String pageSize, YedRespLoanInfoQuery yedRespLoanInfoQuery, EsbRetCodeStandard esbRetCodeStandard) {
        logger.error("借据信息30230006_06接口查询发生异常：" + exception.getMessage());
        //需要反馈异常信息给esb
        logger.info("借据信息30230006_06查询发生异常处理开始");
        yedRespLoanInfoQuery.setPgNo(pageNo);
        //当返回异常时，设置查询到的记录数为0
        yedRespLoanInfoQuery.setTotCnt("0");
        yedRespLoanInfoQuery.setPerPgDsplCnt(pageSize);
        yedRespLoanInfoQuery.setRetCd(esbRetCodeStandard.getValue());
        yedRespLoanInfoQuery.setRetMsg(exception.getMessage());
        yedRespLoanInfoQuery.setAccLoanArryList(new ArrayList<AccLoanArry>());
        logger.info("借据信息30230006_06查询发生异常处理结束");
        exception.printStackTrace();
        return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
                JSONObject.toJSONString(yedRespLoanInfoQuery, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteNullNumberAsZero, SerializerFeature.WriteMapNullValue),
                EsbSysHeadEnums.RetStEnum.FAILURE.getCode(),
                esbRetCodeStandard.getValue(),
                exception.getMessage());
    }

    public void setRespPersonalLoanInfo(String pageNo, String pageSize, YedRespLoanInfoQuery yedRespLoanInfoQuery, Integer totalSize) {
        yedRespLoanInfoQuery.setPgNo((pageNo == null || !pageNo.matches("^[1-9]{1}[0-9]*$")) ? DEFAULT_PAGE_NO : pageNo);
        yedRespLoanInfoQuery.setTotCnt(totalSize.toString());
        yedRespLoanInfoQuery.setPerPgDsplCnt((pageSize == null || !pageSize.matches("^[1-9]{1}[0-9]*$")) ? DEFAULT_PAGE_SIZE : pageSize);
        yedRespLoanInfoQuery.setRetCd(EsbSysHeadEnums.RetStEnum.SUCCESS.getCode());
        yedRespLoanInfoQuery.setRetMsg("查询成功");
    }

    private final String setlCyc(String setlCyc) {
        if (StringUtils.isEmpty(setlCyc) && setlCyc.length() == 0) {
            return "";
        }
        if (setlCyc.length() == 1) {
            return "1" + setlCyc;
        } else {
            return setlCyc;
        }
    }
}
